package cn.xiaopengstack.domain.trade.service.refund;

import cn.xiaopengstack.domain.trade.model.entity.*;
import cn.xiaopengstack.domain.trade.model.valobj.GroupBuyOrderListStatusEnum;
import cn.xiaopengstack.domain.trade.repository.ITradeRepository;
import cn.xiaopengstack.domain.trade.rule.factory.TradeRefundStrategyFactory;
import cn.xiaopengstack.domain.trade.service.IRefundService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author jiangyangang
 */
@Service
@Slf4j
public class RefundService implements IRefundService {
    @Resource
    private ITradeRepository tradeRepository;

    @Resource
    private TradeRefundStrategyFactory refundStrategyFactory;

    @Override
    public TradeRefundResponseEntity refund(TradeRefundRequestEntity tradeRefundRequestEntity) {

        String userId = tradeRefundRequestEntity.getUserId();
        Optional<GroupBuyOrderListEntity> groupBuyOrderListEntityOptional = tradeRepository.queryOrderDetailByOrderId(tradeRefundRequestEntity.getOrderId());

        return groupBuyOrderListEntityOptional.map((orderList) -> {

            // 已退款则直接返回
            if (GroupBuyOrderListStatusEnum.REFUND == orderList.getStatus()) {
                Optional<GroupBuyOrderRefundEntity> refundEntityOptional = tradeRepository.queryRefundByOrderId(orderList.getOrderId(), orderList.getUserId());

                return refundEntityOptional.map((refundOrderEntity) -> TradeRefundResponseEntity
                        .builder()
                        .refundOrderId(refundOrderEntity.getRefundOrderId())
                        .teamId(refundOrderEntity.getTeamId())
                        .userId(refundOrderEntity.getUserId())
                        .build())
                        .orElse(TradeRefundResponseEntity.buildMiss(orderList.getUserId()));
            }

            // 获取拼团组队订单
            Optional<GroupBuyOrderEntity> groupBuyOrder = tradeRepository.queryOrderByTeamId(orderList.getTeamId());
            return groupBuyOrder.map((orderEntity) -> {
                GroupBuyOrderEntity groupBuyOrderEntity = groupBuyOrder.get();
                // 使用退款策略
                try {
                    return refundStrategyFactory.getStrategy(groupBuyOrderEntity.getStatus(), orderList.getStatus()).apply(TradeRefundCommandAggregate
                            .builder()
                                    .groupBuyOrderListEntity(orderList)
                                    .groupBuyOrderEntity(groupBuyOrderEntity)
                                    .tradeRefundRequestEntity(tradeRefundRequestEntity)
                            .build());
                } catch (Exception e) {
                    log.error("退单领域：退款异常", e);
                    return TradeRefundResponseEntity.buildFail(userId);
                }
            }).orElseGet(() -> {
                log.debug("退单领域：没有找到对应的拼团队伍记录。teamId={}", orderList.getTeamId());
                return TradeRefundResponseEntity.buildMiss(userId);
            });
        }).orElseGet(() -> {
            log.debug("退单领域：没有找到对应的拼团记录。orderId={}", tradeRefundRequestEntity.getOrderId());
            return TradeRefundResponseEntity.buildMiss(userId);
        });
    }
}
